#include "resetdialog.h"
#include "ui_resetdialog.h"
#include <qregularexpression.h>
#include "httpmgr.h"

ResetDialog::ResetDialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::ResetDialog)
{
    ui->setupUi(this);

    //清除错误提示
    ui->reset_err_tips->clear();

    //连接用户输入结束之后的槽函数，回调进行检查
    connect(ui->user_edit,&QLineEdit::editingFinished,this,[this](){
        checkUserValid();
    });

    connect(ui->message_edit,&QLineEdit::editingFinished,this,[this](){
        checkEmailValid();
    });

    connect(ui->newpasswd_edit,&QLineEdit::editingFinished,this,[this](){
        checkPassValid();
    });

    connect(ui->confirm_edit,&QLineEdit::editingFinished,this,[this](){
        checkConfirmValid();
    });

    connect(ui->varfity_edit,&QLineEdit::editingFinished,this,[this](){
        checkVarifyValid();
    });

    //连接http与档期啊能处理的魔窟啊
    connect(HttpMgr::GetInstance().get(),&HttpMgr::sig_reset_mode_finish,this,&ResetDialog::slot_reset_mod_finish);

    reqID_Map_function.insert(ReqId::ID_RESET_PASSWD,[this](QJsonObject jsonObj){
        int error = jsonObj["error"].toInt();
        if(error != ErrorCodes::SUCCESS){
            ShowTips(tr("参数错误"),false);
            return;
        }
        auto email = jsonObj["email"].toString();
        ShowTips(tr("密码已经修改"), true);
        qDebug()<< "email is " << email ;
    });


}

ResetDialog::~ResetDialog()
{
    delete ui;
}

//点击之后就返回创建主界面
void ResetDialog::on_return_button_clicked()
{

    emit switchlogin();
}

bool ResetDialog::checkUserValid()
{
    if(ui->user_edit->text() == "")
    {
        AddErr(TipErr::TIP_USER_ERR, tr("用户名不能为空"));
        return false;
    }

    DelErr(TipErr::TIP_USER_ERR);
    return true;

}

bool ResetDialog::checkEmailValid()
{
    //验证邮箱的地址正则表达式
    auto email = ui->message_edit->text();
    // 邮箱地址的正则表达式
    QRegularExpression regex(R"((\w+)(\.|_)?(\w*)@(\w+)(\.(\w+))+)");
    bool match = regex.match(email).hasMatch(); // 执行正则表达式匹配
    if(!match){
        //提示邮箱不正确
        AddErr(TipErr::TIP_EMAIL_ERR, tr("邮箱地址不正确"));
        return false;
    }

    DelErr(TipErr::TIP_EMAIL_ERR);
    return true;

}

bool ResetDialog::checkPassValid()
{
    auto pass = ui->newpasswd_edit->text();

    if(pass.length() < 6 || pass.length()>15){
        //提示长度不准确
        AddErr(TipErr::TIP_PWD_ERR, tr("密码长度应为6~15"));
        return false;
    }

    // 创建一个正则表达式对象，按照上述密码要求
    // 这个正则表达式解释：
    // ^[a-zA-Z0-9!@#$%^&*]{6,15}$ 密码长度至少6，可以是字母、数字和特定的特殊字符
    QRegularExpression regExp("^[a-zA-Z0-9!@#$%^&*]{6,15}$");
    bool match = regExp.match(pass).hasMatch();
    if(!match){
        //提示字符非法
        AddErr(TipErr::TIP_PWD_ERR, tr("不能包含非法字符"));
        return false;;
    }

    DelErr(TipErr::TIP_PWD_ERR);

    return true;

}

bool ResetDialog::checkConfirmValid()
{
    if(ui->confirm_edit->text()!=ui->newpasswd_edit->text())
    {
        AddErr(TipErr::TIP_CONFIRM_ERR, tr("两次输入密码不一致"));
        return false;
    }
    DelErr(TipErr::TIP_CONFIRM_ERR);
    return true;
}

bool ResetDialog::checkVarifyValid()
{
    auto pass = ui->varfity_edit->text();
    if(pass.isEmpty()){
        AddErr(TipErr::TIP_VARIFY_ERR, tr("验证码不能为空"));
        return false;
    }

    DelErr(TipErr::TIP_VARIFY_ERR);
    return true;
}

void ResetDialog::AddErr(TipErr tip, QString str)
{
    this->_err_map.insert(tip,str);

    //直接展示字符串
    ShowTips(str,false);
}

void ResetDialog::DelErr(TipErr tip)
{
    //检查是否存在该错误，如果有，直接删除？似乎不用作检测，直接山
    _err_map.remove(tip);
    if(_err_map.empty())
    {
        ui->reset_err_tips->clear();

        return ;
    }
    ShowTips(_err_map.first(),false);
}

bool ResetDialog::checkAllVaild()
{
    if(ui->user_edit->text()==""||ui->message_edit->text()==""||ui->newpasswd_edit->text()==""||ui->confirm_edit->text()==""||ui->varfity_edit->text()=="")
    {
        return false;
    }
    else
    {
        return true;
    }
}

void ResetDialog::ShowTips(QString str, bool flag)
{
    if(flag)
    {
        ui->reset_err_tips->setText(str);
        ui->reset_err_tips->setProperty("state","normal");      //设置属性，从而设置动画
    }
    else
    {
        ui->reset_err_tips->setText(str);
        ui->reset_err_tips->setProperty("state","err");
    }
    repolish(ui->reset_err_tips);
}

//这一层主要处理模块业务逻辑，如果或者模块有更多的业务ID，可以使用更多的hander实现对ID的不同请求
//这里单纯使用实时的是是模块的功能
void ResetDialog::slot_reset_mod_finish(ReqId id, QString res, ErrorCodes err)
{
    //讲json的信息拿出来，json反序列化
    if(err!=ErrorCodes::SUCCESS)
    {
        ShowTips(tr("网络处理失败"),false);
        return;
    }

    QJsonDocument jsonDoc = QJsonDocument::fromJson(res.toUtf8());
    //json解析错误
    if(jsonDoc.isNull()){
        ShowTips(tr("json解析错误"),false);
        return;
    }

    //json解析错误
    if(!jsonDoc.isObject()){
        ShowTips(tr("json解析错误"),false);
        return;
    }

    QJsonObject jsonObj = jsonDoc.object();

    reqID_Map_function[id](jsonObj);


    //编译期：生成一个仿函数，以及一系列的代码，这些代码在运行期做的事是：将参数固定住，然后存放在容器中，最后待会使用
    //如果有这样的需求，将一个可调用对象存储，那就使用function进行存储，具体的处理方法已经放到微信了
    //这个过程其实就和函数传参的代价是一样的
    pushFunction(id,[this](QJsonObject jsonObj){
        int error = jsonObj["error"].toInt();
        if(error != ErrorCodes::SUCCESS){
            ShowTips(tr("参数错误"),false);
            return;
        }
        auto email = jsonObj["email"].toString();
        ShowTips(tr("密码已经修改"), true);
        qDebug()<< "email is " << email ;
    },jsonObj);

    reqID_Map_function_1[id]();

}




void ResetDialog::on_confirm_button_clicked()
{
    if(!checkAllVaild())
    {
        //说明有空，不可以发
        ShowTips("有空白，不可以发送",false);
        return;
    }
    else
    {
        //检查是否err_list是否有
        if(_err_map.empty())
        {
            //没有错误，可以调用接口发送出去

            QJsonObject json_obj;
            json_obj["user"] = ui->user_edit->text();
            json_obj["email"] = ui->message_edit->text();
            json_obj["newpasswd"] = ui->newpasswd_edit->text();
            json_obj["confirm"] = ui->confirm_edit->text();
            json_obj["varifycode"] = ui->varfity_edit->text();

            //叫欸HTTP管理器进行发送
            HttpMgr::GetInstance()->PostHttpreq(QUrl(gate_url_prefix+"/user_resetpasswd"),
                                                json_obj, ReqId::ID_RESET_PASSWD,Modules::RESETPASSWDMOD);

            ShowTips("没有输入错误，可以发送",true);
            return;
        }
        else
        {
            ShowTips("存在输入错误，拒绝发送",false);
            //有错误，不可以发送
            return;
        }
    }

}


//编译期有什么表现吗？没有直接用到模板，单纯就是，此代码，运行时，接受一个参数，绑定一个参数，存储一个函数对象
void ResetDialog::pushFuncMap(ReqId id,std::function<void(const QJsonObject&)> fun,const QJsonObject& Qjson)
{
    //绑定第一个参数，固定参数
    auto funObj=std::function<void()>(std::bind(fun,Qjson));
    //存储函数对象
    reqID_Map_function_1.insert(id,funObj);
}

